﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using V = Science.Mathematics.VectorCalculus;

namespace VectorCalculus5Ed.Chapter8.Section4
{
    public class Example05
    {
        public Example05()
		{
		}
		private string result;
		public string Result
		{
			get{return result;}
		}
        public void Compute()
        {
            V.Function.ToLastType<double[], double[]> ff
                = new V.Function.ToLastType<double[], double[]>(surface);
            V.Surface s = new V.Surface(ff);
            s.Parameter1StartValue = 0.0;
            s.Parameter1EndValue = 3.0;
            s.Parameter2StartValue = 0.0;
            s.Parameter2EndValue = 2.0 * Math.PI;

            V.Function.ToLastType<double[], double> gg
                = new V.Function.ToLastType<double[], double>(volume);
            double[] from = { -1.0, -1.0, -1.0 };
            double[] to = { 1.0, 1.0, 1.0 };
            V.Volume v = new V.Volume(from, to, gg);

            V.Function.ToLastType<double[], double[]> F
               = new V.Function.ToLastType<double[], double[]>(vectorField);

            V.GaussDivergenceTheorem obj = new V.GaussDivergenceTheorem(v, F, s);
            obj.Compute();

            result += obj.LeftHandSideBestEstimation.ToString() + "\r\n";
            result += obj.LeftHandSideStandardDeviation.ToString() + "\r\n";
            result += obj.RightHandSideBestEstimation.ToString() + "\r\n";
            result += obj.RightHandSideStandardDeviation.ToString() + "\r\n";

            result += (Math.PI).ToString() + "\r\n";
        }
        private double[] surface(double[] u)
        {
            double[] x = new double[3];
            if (u[0] > 0.0 & u[0] < 1.0)
            {
                x[0] = u[0] * Math.Cos(u[1]);
                x[1] = u[0] * Math.Sin(u[1]);
                x[2] = 1.0;
            }
            else if (u[0] > 1.0 & u[0] < 2.0)
            {
                x[0] = Math.Cos(u[1]);
                x[1] = Math.Sin(u[1]);
                x[2] = 1.0 - 2.0*(u[0] - 1.0);
            }
            else
            {
                x[0] = (u[0] - 2.0) * Math.Cos(u[1]);
                x[1] = (u[0] - 2.0) * Math.Sin(u[1]);
                x[2] = -1.0;
            }
            return x;
        }
        private double volume(double[] x)
        {
            if (x[2] > 1.0 | x[2] < -1.0) return 1.0;
            else if (x[0] * x[0] + x[1] * x[1] > 1.0) return 1.0;
            else return -1.0;
        }
        private double[] vectorField(double[] x)
        {
            double[] f = new double[3];
            f[0] = x[0] * x[1] * x[1];
            f[1] = x[0] * x[0] * x[1];
            f[2] = x[1];
            return f;
        }
    }
}
/*
3.14274388289847
0.00107978960972351
3.14378784836556
0.00188964271356293
3.14159265358979
*/
